#!/usr/bin/env python
#coding=utf-8
import os
import sys
import json

sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../"))
import loader

class ResterStringBuilder(loader.DBTableBase):
	def __init__(self):
		pass

	def __init__(self, row, cursor):
		super(ResterStringBuilder, self).__init__(row, cursor)

	def __get_real_val_by_key(self, key):
		if key.find(".") > 0:
			ks = key.split(".")
			if ks[0] not in self:
				return ""
			val = self[ks[0]]
			if ks[1] not in val:
				return ""
			val = val[ks[1]]
		else:
			if key not in self:
				return ""
			val = self[key]
		if type(val) in (tuple, list):
			v = str(len(val))
		else:
			v = str(val)
		return v

	def __get_val_by_key(self, key, xargs=None):
		val = self.__get_real_val_by_key(key)
		return self.value_fixer(key, val, xargs)

	# Override to fix values by key
	def value_fixer(self, key, val, xargs=None):
		return val

	def __xmlesc(self, txt):
		txt = txt.replace("&", "&amp;")
		txt = txt.replace("<", "&lt;")
		txt = txt.replace(">", "&gt;")
		txt = txt.replace('"', "&quot;")
		txt = txt.replace("'", "&apos;")
		return txt

	def __getKeys(self, keys=None):
		if keys:
			return keys
		fields = self.getFields()
		if len(fields) > 0:
			return fields
		return self.keys()

	def getXMLInfo(self, keys=None, xargs=None):
		item_keys = self.__getKeys(keys)
		resStr = ""
		for k in item_keys:
			v = self.__get_val_by_key(k, xargs)
			v = self.__xmlesc(v)
			resStr += "<%s>%s</%s>\n" % (k, v, k)
		return resStr

	def getJSONInfo(self, keys=None, xargs=None):
		item_keys = self.__getKeys(keys)
		resObj = {}
		for k in item_keys:
			resObj[k] = self.__get_val_by_key(k, xargs)
		return json.dumps(resObj)

	def getDataTableInfo(self, keys=None, xargs=None, extra_vals=None):
		vals = []
		item_keys = self.__getKeys(keys)
		for k in item_keys:
			v = self.__get_val_by_key(k, xargs)
			vals.append('"' + v.replace('"', '') + '"')
		if extra_vals:
			for val in extra_vals:
				vals.append('"' + str(val) + '"')
		return "[" + ",".join(vals) + "]"

	def getStr(self, xargs=None, extra_keys=None, extra_vals=None):
		if xargs and "format" in xargs:
			if xargs["format"] == "xml":
				return self.getXMLInfo(extra_keys, xargs)
			return self.getJSONInfo(extra_keys, xargs)
		else:
			return self.getDataTableInfo(extra_keys, xargs, extra_vals)

class ResterHelper(object):
	@staticmethod
	def _build_xml_content(array, xargs):
		resStr = '<items>\n'
		for item in array:
			resStr += '<item>\n'
			resStr += item.getStr(xargs)
			resStr += '</item>\n'
		resStr += '</items>\n'
		return resStr

	@staticmethod
	def _build_datatable_content(array, xargs):
		resStr = '{ "data": [\n'
		vals = [k.getStr(xargs) for k in array]
		resStr = resStr + ",\n".join(vals)
		resStr += '\n] }\n'
		return resStr

	@staticmethod
	def build_array_content(array, xargs):
		if xargs and "format" in xargs and xargs["format"] == "xml":
			resStr = ResterHelper._build_xml_content(array, xargs)
		else:
			resStr = ResterHelper._build_datatable_content(array, xargs)
		return resStr

	@staticmethod
	def match_xargs_filter(item, xargs):
		if not xargs:
			return True

		for k, v in xargs.items():
			# Ignore not recoginized filters
			if k not in item:
				continue
			if "__greater" not in xargs and item[k] == v:
				continue
			if isinstance(item[k], int):
				if "__greater" in xargs and item[k] > int(v):
					continue
				elif str(item[k]) == v:
					continue
			if isinstance(item[k], bool) and str(item[k]).lower() == v:
				continue
			if type(item[k]) in (tuple, list):
				bVal = len(item[k]) > 0
				if str(bVal).lower() == v:
					continue
			# Value not matched or value type not recoginized
			return False
		return True

	@staticmethod
	def filter_contents(array, xargs):
		if not xargs:
			return array
		return (item for item in array if ResterHelper.match_xargs_filter(item, xargs))
